home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Night Owl 6
/
Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso
/
001a
/
mskrmsrc.zip
/
MSNUT1.ASM
< prev
next >
Wrap
Assembly Source File
|
1991-10-24
|
12KB
|
590 lines
NAME MSNUT1
; File MSNUT1.ASM
; Provides various Intel 8088 level operations, including
; display facilities (via msg buffer or DOS) for char, strings, etc.
;
; Copyright 1991, University of Waterloo.
; Copyright (C) 1991, Trustees of Columbia University in the
; City of New York. Permission is granted to any individual or
; institution to use, copy, or redistribute this software as long as
; it is not sold for profit and this copyright notice is retained.
;
; Written by Erick Engelke of the University of Waterloo, Waterloo,
; Ontario, Canada,
; and by Joe R. Doupnik, Utah State University,
; jrd@cc.usu.edu, jrd@usu.Bitnet.
;
; Edit history
; 6 Sept 1991 v3.11
; Last Edit
; 6 Sept 1991
cr equ 0dh
lf equ 0ah
conout equ 2
dos equ 21h
BIOSCLK equ 046ch
HI_MAX equ 018h
LO_MAX equ 0b0h
_TEXT SEGMENT WORD PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT WORD PUBLIC 'DATA'
_DATA ENDS
CONST SEGMENT WORD PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT WORD PUBLIC 'BSS'
_BSS ENDS
DGROUP GROUP CONST, _BSS, _DATA
ASSUME CS: _TEXT, DS: DGROUP, SS: DGROUP
_DATA SEGMENT
extrn _doslevel:word, _msgcnt:word, _msgbuf:byte,_display_mode:byte
_DATA ENDS
_TEXT segment
; Compute 1's-complement sum of data buffer
; unsigned checksum( unsigned word *buf, unsigned cnt)
public _checksum
_checksum proc near
push bp
mov bp,sp
push si
push bx
push cx
push dx
mov si,[bp+4+0] ; offset of data to be checked
mov cx,[bp+4+2] ; cx = cnt
mov bl,cl
shr cx,1 ; group into words
xor dx,dx ; set checksum to 0
cld
jcxz chk3
clc
chk1: lodsw
adc dx,ax
loop chk1
; resolve remainder
chk2: adc dx,0
jc chk2
chk3: and bl,1
jz chk5
xor ah,ah
lodsb
clc
add dx,ax
chk4: adc dx,0
jc chk4
chk5: mov ax,dx ; result into ax
or ax,ax
jnz chk6
mov ax,0ffffh
chk6: pop dx
pop cx
pop bx
pop si
pop bp
ret
_checksum endp
; intel - convert intel <--> bigendian
;
;*************************************************************************
; USAGE: ULONG intel( ULONG val )
; - convert to intel format
;*************************************************************************
public _intel
_intel proc near
push bp
mov bp,sp
mov AX,[BP+4+2]
mov DX,[BP+4+0]
xchg AL, AH
xchg DL, DH
pop bp
ret
_intel endp
;*************************************************************************
; USAGE: UINT intel16( UINT val )
; - convert to intel format
;*************************************************************************
public _intel16
_intel16 proc near
push bp
mov bp,sp
mov AX,[BP+4+0]
xchg AL,AH
pop bp
ret
_intel16 endp
; int ourmod(int top, int bottom)
public _ourmod
_ourmod proc near
push bp
mov bp,sp
push bx
mov ax,[bp+4+0] ; top number
mov bx,[bp+4+2] ; bottom number (radix)
xor dx,dx
or bx,bx ; bottom is zero?
jz ourmod1 ; yes, return zero
div bx
ourmod1:mov ax,dx ; return remainder
pop bx
pop bp
ret
_ourmod endp
; int ourdiv(int top, int bottom)
public _ourdiv
_ourdiv proc near
push bp
mov bp,sp
push bx
mov ax,[bp+4+0] ; top
mov bx,[bp+4+2] ; bottom
xor dx,dx
or bx,bx ; divide by zero?
jz outdiv1 ; z = yes, divide by one
div bx
outdiv1:pop bx
pop bp ; quotient is returned in ax
ret
_ourdiv endp
; int ourlmod(long top, int bottom)
public _ourlmod
_ourlmod proc near
push bp
mov bp,sp
push bx
mov ax,[bp+4+0] ; top lower 16 bits
mov dx,[bp+4+2] ; top upper 16 bits
mov bx,[bp+4+4] ; bottom
or bx,bx ; zero?
jz outlmo1 ; z = yes divide by 2^16 and quit
div bx
outlmo1:mov ax,dx ; return remainder in ax
pop bx
pop bp
ret
_ourlmod endp
; int ourldiv(long top, int bottom)
public _ourldiv
_ourldiv proc near
push bp
mov bp,sp
push bx
mov ax,[bp+4+0] ; top lower 16 bits
mov dx,[bp+4+2] ; top upper 16 bits
mov bx,[bp+4+4] ; bottom
cmp dx,bx ; about to overflow?
jae ourldiv1 ; ae = yes, return 0xffffh
div bx
xor dx,dx ; clear remainder (high order ret)
pop bx
pop bp ; quotient is returned in dx:ax
ret
ourldiv1:mov ax,0ffffh ; overflow indication
xor dx,dx ; clear high order
pop bx
pop bp
ret
_ourldiv endp
; long ourlmul(long top, int bottom)
public _ourlmul
_ourlmul proc near
push bp
mov bp,sp
push bx
push cx
mov ax,[bp+4+2] ; top upper 16 bits
mov bx,[bp+4+4] ; bottom
mul bx
mov cx,ax ; save product (no overflow noted)
mov ax,[bp+4+0] ; top lower 16 bits
mul bx
adc dx,cx ; new upper 16 bits
pop cx
pop bx
mov sp,bp
pop bp ; long product is returned in dx:ax
ret
_ourlmul endp
; void * bcopy(src, dest, count)
; void *dest, *src;
; size_t count;
; copy count bytes from src to dest
public _bcopy
_bcopy proc near
push bp
mov bp,sp
push es
push si
push di
push cx
mov ax,ds ; set to same data segment
mov es,ax
mov si,[bp+4+0] ; offset of source
mov di,[bp+4+2] ; offset of destination
mov cx,[bp+4+4] ; count
cld
push di ; push dest address for return
jcxz bcopy2 ; z = nothing to copy
or di,di ; is destination NULL?
jz bcopy2 ; z = yes, don't do a thing
cmp si,di ; is source after destination?
ja bcopy1 ; a = yes, no overlap problem
je bcopy2 ; e = same place, do nothing
add di,cx ; start at the ends
dec di
add si,cx
dec si
std ; work backward
bcopy1: rep movsb
bcopy2: pop ax ; recover return destination
cld
pop cx
pop di
pop si
pop es
mov sp,bp
pop bp
ret
_bcopy endp
; void * memset(dest, c, count)
; void *dest;
; char c;
; size_t count;
public _memset
_memset proc near
push bp
mov bp,sp
push es
push di
push cx
mov ax,ds ; setup data segment
mov es,ax
mov di,[bp+4+0] ; offset of destination
or di,di ; is it NULL?
jz memset1 ; z = yes, don't do a thing
push di ; save dest for return
mov al,[bp+4+2] ; byte of character c
mov ah,al
mov cx,[bp+4+4] ; count
jcxz memset1 ; z = do nothing
cld
shr cx,1
jnc memset2
stosb
memset2:rep stosw
pop ax ; return pointer to destination
memset1:pop cx
pop di
pop es
mov sp,bp
pop bp
ret
_memset endp
;
; Timer routines - use set_*timeout to receive a clock value which
; can later be tested by calling chk_timeout with
; that clock value to determine if a timeout has
; occurred. chk_timeout returns 0 if NOT timed out.
;
;
; Usage :
; long set_timeout( int seconds );
; long set_ttimeout( int pc_ticks );
; int chk_timeout( long value );
;
; (c) 1990 University of Waterloo,
; Faculty of Engineering,
; Engineering Microcomputer Network Development Office
;
; version
;
; 0.1 7-Nov -1990 E. P. Engelke
;
;
public _set_ttimeout
_set_ttimeout proc near
push bp
mov bp,sp
push es
xor AX, AX
cwd
mov ES, AX
mov AX, [BP+4+0]
pushf
cli
add AX, ES:[BIOSCLK+0];
adc DX, ES:[BIOSCLK+2];
popf
pop es
pop bp
ret
_set_ttimeout endp
public _set_timeout
_set_timeout proc near
push bp
mov bp,sp
push es
push cx
xor AX, AX ; reference low memory
mov ES, AX
mov AX,[BP+4+0] ; seconds
xor dx,dx
mov cx,1165
mul cx ; 1165/64 = 18.203...
mov CX,6
tmp: shr DX,1
rcr AX,1
loop tmp
pushf
cli
add AX,ES:[BIOSCLK+0]
adc DX,ES:[BIOSCLK+2]
popf
pop cx
pop es
pop bp
ret
_set_timeout endp
public _chk_timeout
_chk_timeout proc near
push bp
mov bp,sp
push cx
push es
xor AX, AX
mov ES, AX
pushf
cli
mov CX,ES:[BIOSCLK+0]
mov BX,ES:[BIOSCLK+2]
popf
pop es
mov AX,[BP+4+0] ; timeout value
mov DX,[BP+4+2]
cmp DX,BX ; if timeout < clock, has expired
jb ret_tru
cmp AX, CX
jbe ret_tru
; may have gone over by one day
sub AX, LO_MAX
sbb DX, HI_MAX
jc ret_fal ; c = nope, timeout is today
; test timeout new values
cmp DX, BX
jb ret_tru
cmp AX, CX
ja ret_fal
ret_tru:mov AX, 1 ; say have timed out
pop cx
pop bp
ret
ret_fal:xor AX, AX ; say have not timed out
pop cx
pop bp
ret
_chk_timeout endp
; unsigned long realclock(void)
public _realclock
_realclock proc near ; get Bios time of day dword
push es
xor ax,ax ; reference low memory
mov es,ax
pushf
cli
mov ax,es:[BIOSCLK+0] ; return Bios time of day tick count
mov dx,es:[BIOSCLK+2]
popf
pop es
ret
_realclock endp
; void _chkstk()
; {
; ;
; }
public __chkstk, __aNchkstk
__chkstk proc near ; MSC v5.1
__aNchkstk equ this byte ; MSC v6.00
pop bx ; pop return address
sub sp,ax ; down adjust stack pointer
jmp bx ; return the no-stack way
__chkstk endp
; void
; outch(char ch)
; Sends character to the screen via the msgbuf buffer if operating at
; interrupt level, or via DOS if operating at task level.
public _outch
_outch proc near
push bp
mov bp,sp
push ax
push bx
cmp _display_mode,0 ; quiet screen?
je outch3 ; e = yes
mov al,[bp+4] ; get the character
cmp _doslevel,0 ; at DOS task level?
je outch1 ; e = no
mov ah,conout ; use DOS
push dx
mov dl,al
int dos
pop dx
jmp short outch3
outch1: cmp _msgcnt,256 ; is buffer filled?
ja outch3 ; a = yes, discard this byte
mov bx,_msgcnt
mov _msgbuf[bx],al
inc _msgcnt
outch3: pop bx
pop ax
mov sp,bp
pop bp
ret
_outch endp
; void
; outsn(char * string, int count)
; display counted string
public _outsn
_outsn proc near
push bp
mov bp,sp
push ax
push si
mov si,[bp+4] ; string address
mov cx,[bp+4+2] ; string length
cld
outsn1: lodsb
or al,al
jz outsn2
cmp al,cr ; convert cr to cr lf
jnz outsn3
push ax
call _outch
pop ax
outsn3: push ax
call _outch
pop ax
loop outsn1
outsn2: pop si
pop ax
mov sp,bp
pop bp
ret
_outsn endp
; void
; outs(char * string)
; display asciiz string
public _outs
_outs proc near
push bp
mov bp,sp
push ax
push si
mov si,[bp+4] ; asciiz string address
cld
outs1: lodsb
or al,al
jz outs2
cmp al,cr ; convert cr to cr lf
jnz outs3
push ax
call _outch
pop ax
outs3: push ax
call _outch
pop ax
jmp outs1
outs2: pop si
pop ax
mov sp,bp
pop bp
ret
_outs endp
; void
; outhex(char c)
; display char in hex
public _outhex
_outhex proc near
push bp
mov bp,sp
push ax
mov ax,[bp+4] ; incoming character
mov cl, 4
shr al, cl
call outh
mov ax,[bp+4]
call outh
pop ax
mov sp,bp
pop bp
ret
; worker for outhex
outh proc near
and al,0fh
cmp al,9
jbe outh1
add al,'A' - '9' - 1
outh1: add al,'0'
push ax
call _outch
pop ax
ret
outh endp
_outhex endp
; output a string of hex chars
; void
; outhexes(char * string, int count )
public _outhexes
_outhexes proc near
push bp
mov bp,sp
push ax
push si ; preserve such things
mov si,[bp+4] ; get string pointer
mov cx,[bp+4+2] ; get char count
cld
outhexs1:lodsb ; read a byte
push cx ; save loop counter
push ax
call _outhex ; display as hex pair
add sp,2 ; clean stack
pop cx
loop outhexs1 ; do count's worth
pop si
pop ax
mov sp,bp
pop bp
ret
_outhexes endp
_TEXT ends
end